View Javadoc
1 /* 2 AntMake 3 4 Copyright (C) 2004 Jose San Leandro Armend?riz 5 jsanleandro@yahoo.es 6 chousz@yahoo.com 7 8 This library is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public 10 License as published by the Free Software Foundation; either 11 version 2 of the License, or (at your option) any later version. 12 13 This library is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 General Public License for more details. 17 18 You should have received a copy of the GNU General Public 19 License along with this library; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 22 Thanks to ACM S.L. for distributing this library under the GPL license. 23 Contact info: jsr000@terra.es 24 Postal Address: c/Playa de Lagoa, 1 25 Urb. Valdecaba?as 26 Boadilla del monte 27 28660 Madrid 28 Spain 29 30 ****************************************************************************** 31 This class is based on ChangeLogParser 32 included in Ant distribution, and whose license details 33 are the following. 34 35 * 36 * The Apache Software License, Version 1.1 37 * 38 * Copyright (c) 2002 The Apache Software Foundation. All rights 39 * reserved. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 45 * 1. Redistributions of source code must retain the above copyright 46 * notice, this list of conditions and the following disclaimer. 47 * 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in 50 * the documentation and/or other materials provided with the 51 * distribution. 52 * 53 * 3. The end-user documentation included with the redistribution, if 54 * any, must include the following acknowlegement: 55 * "This product includes software developed by the 56 * Apache Software Foundation (http://www.apache.org/)." 57 * Alternately, this acknowlegement may appear in the software itself, 58 * if and wherever such third-party acknowlegements normally appear. 59 * 60 * 4. The names "Ant" and "Apache Software 61 * Foundation" must not be used to endorse or promote products derived 62 * from this software without prior written permission. For written 63 * permission, please contact apache@apache.org. 64 * 65 * 5. Products derived from this software may not be called "Apache" 66 * nor may "Apache" appear in their names without prior written 67 * permission of the Apache Group. 68 * 69 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 70 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 71 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 72 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 73 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 74 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 75 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 76 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 77 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 78 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 79 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 80 * SUCH DAMAGE. 81 * ==================================================================== 82 * 83 * This software consists of voluntary contributions made by many 84 * individuals on behalf of the Apache Software Foundation. For more 85 * information on the Apache Software Foundation, please see 86 * <http://www.apache.org/>. 87 * 88 89 ****************************************************************************** 90 * 91 * Filename: $RCSfile: ChangeLogParser.java,v $ 92 * 93 * Author: Jose San Leandro Armend?riz 94 * 95 * Description: Knows how to parse "cvs log" command output. 96 * 97 * Last modified by: $Author: chous $ at $Date: 2004/01/29 06:44:21 $ 98 * 99 * File version: $Revision: 1.3 $ 100 * 101 * Project version: $Name: $ 102 * 103 * $Id: ChangeLogParser.java,v 1.3 2004/01/29 06:44:21 chous Exp $ 104 * 105 */ 106 package org.acmsl.antmake.cvslib; 107 108 /* 109 * Importing project classes. 110 */ 111 import org.acmsl.antmake.cvslib.RcsFile; 112 113 /* 114 * Importing JDK classes. 115 */ 116 import java.text.DateFormat; 117 import java.text.ParseException; 118 import java.text.SimpleDateFormat; 119 import java.util.ArrayList; 120 import java.util.Collection; 121 import java.util.Date; 122 import java.util.HashMap; 123 import java.util.Iterator; 124 import java.util.Map; 125 import java.util.TimeZone; 126 127 /* 128 * Importing Commons Logging classes. 129 */ 130 import org.apache.commons.logging.LogFactory; 131 132 /*** 133 * Knows how to parse "cvs log" command output. 134 * @author <a href="mailto:jsanleandro@yahoo.es" 135 >Jose San Leandro</a>, based on 136 * <a href="mailto:peter@apache.org">Peter Donald</a>'s 137 * ChangeLogParser. It's package-protected, so it had to be basically copied 138 * and pasted. 139 * @version $Revision: 1.3 $ 140 * @see org.apache.tools.ant.taskdefs.cvslib.ChangeLogParser 141 */ 142 public class ChangeLogParser 143 { 144 /*** 145 * A cached empty CvsEntry array. 146 */ 147 protected static final CvsEntry[] EMPTY_CVSENTRY_ARRAY = new CvsEntry[0]; 148 149 //private static final int GET_ENTRY = 0; 150 private static final int GET_FILE = 1; 151 private static final int GET_DATE = 2; 152 private static final int GET_COMMENT = 3; 153 private static final int GET_REVISION = 4; 154 private static final int GET_PREVIOUS_REV = 5; 155 156 /*** 157 * The date format returned by cvs log. 158 */ 159 public static final DateFormat CVS_LOG_DATE_FORMAT = 160 new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 161 162 static 163 { 164 TimeZone t_TimeZone = TimeZone.getTimeZone("UTC"); 165 CVS_LOG_DATE_FORMAT.setTimeZone(t_TimeZone); 166 } 167 168 /*** 169 * The file name. 170 */ 171 private String m__strName; 172 173 /*** 174 * The date. 175 */ 176 private String m__strDate; 177 178 /*** 179 * The author. 180 */ 181 private String m__strAuthor; 182 183 /*** 184 * The comment. 185 */ 186 private String m__strComment; 187 188 /*** 189 * The revision. 190 */ 191 private String m__strRevision; 192 193 /*** 194 * The previous revision. 195 */ 196 private String m__strPreviousRevision; 197 198 /*** 199 * The variable indicating the current state. 200 */ 201 private int m__iCurrentState; 202 203 /*** 204 * The RCS files. 205 */ 206 private Map m__mEntries; 207 208 /*** 209 * Creates a ChangeLogParser. 210 */ 211 public ChangeLogParser() 212 { 213 inmutableSetCurrentState(GET_FILE); 214 } 215 216 /*** 217 * Specifies the name. 218 * @param name the name of the current CVS file being processed. 219 */ 220 protected void setName(String name) 221 { 222 m__strName = name; 223 } 224 225 /*** 226 * Retrieves the name of the current CVS file being processed. 227 * @return such information. 228 */ 229 protected String getName() 230 { 231 return m__strName; 232 } 233 234 /*** 235 * Specifies the date. 236 * @param date the date of the current CVS file being processed. 237 */ 238 protected void setDate(String date) 239 { 240 m__strDate = date; 241 } 242 243 /*** 244 * Retrieves the date of the current CVS file being processed. 245 * @return such information. 246 */ 247 protected String getDate() 248 { 249 return m__strDate; 250 } 251 252 /*** 253 * Specifies the author. 254 * @param author the author of the current CVS file being processed. 255 */ 256 protected void setAuthor(String author) 257 { 258 m__strAuthor = author; 259 } 260 261 /*** 262 * Retrieves the author of the current CVS file being processed. 263 * @return such information. 264 */ 265 protected String getAuthor() 266 { 267 return m__strAuthor; 268 } 269 270 /*** 271 * Specifies the comment. 272 * @param comment the comment of the CVS file being processed. 273 */ 274 protected void setComment(String comment) 275 { 276 m__strComment = comment; 277 } 278 279 /*** 280 * Retrieves the comment of the CVS file being processed. 281 * @return such information. 282 */ 283 protected String getComment() 284 { 285 return m__strComment; 286 } 287 288 /*** 289 * Specifies the revision. 290 * @param revision the revision of the current CVS file being processed. 291 */ 292 protected void setRevision(String revision) 293 { 294 m__strRevision = revision; 295 } 296 297 /*** 298 * Retrieves the revision of the current CVS file being processed. 299 * @return such information. 300 */ 301 protected String getRevision() 302 { 303 return m__strRevision; 304 } 305 306 /*** 307 * Specifies the previous revision. 308 * @param previousRevision the previous revision of the current CVS file 309 * being processed. 310 */ 311 protected void setPreviousRevision(String previousRevision) 312 { 313 m__strPreviousRevision = previousRevision; 314 } 315 316 /*** 317 * Retrieves the previous revision of the current CVS file being processed. 318 * @return such information. 319 */ 320 protected String getPreviousRevision() 321 { 322 return m__strPreviousRevision; 323 } 324 325 /*** 326 * Specifies the current state of the parser. 327 * @param state the current state of the parser. 328 */ 329 private void inmutableSetCurrentState(int state) 330 { 331 m__iCurrentState = state; 332 } 333 334 /*** 335 * Specifies the current state of the parser. 336 * @param state the current state of the parser. 337 */ 338 protected void setCurrentState(int state) 339 { 340 inmutableSetCurrentState(state); 341 } 342 343 /*** 344 * Retrieves the current state of the parser. 345 * @return such information. 346 */ 347 protected int getCurrentState() 348 { 349 return m__iCurrentState; 350 } 351 352 /*** 353 * Specifies the CVS entries map. 354 * @param map the map. 355 */ 356 protected void setEntries(Map map) 357 { 358 m__mEntries = map; 359 } 360 361 /*** 362 * Retrieves the CVS entries map. 363 * @return such map. 364 */ 365 protected Map getEntries() 366 { 367 return m__mEntries; 368 } 369 370 /*** 371 * Retrieves the list of RCS entries as an array. 372 * @return such items. 373 */ 374 public CvsEntry[] getEntrySetAsArray() 375 { 376 CvsEntry[] result = EMPTY_CVSENTRY_ARRAY; 377 378 Map t_mEntries = getEntries(); 379 380 if (t_mEntries != null) 381 { 382 result = new CvsEntry[t_mEntries.size()]; 383 384 Collection t_cEntries = t_mEntries.values(); 385 386 if (t_cEntries != null) 387 { 388 Iterator t_EntryIterator = t_cEntries.iterator(); 389 390 int t_iEntryIndex = 0; 391 392 while ( (t_EntryIterator != null) 393 && (t_EntryIterator.hasNext())) 394 { 395 result[t_iEntryIndex++] = 396 (CvsEntry) t_EntryIterator.next(); 397 } 398 } 399 } 400 401 return result; 402 } 403 404 /*** 405 * Receives notification about the process writing 406 * to standard output. 407 * @param line the last line read. 408 */ 409 public void stdout(String line) 410 { 411 switch(getCurrentState()) 412 { 413 case GET_FILE: 414 // make sure attributes are reset when 415 // working on a 'new' file. 416 reset(); 417 processFile(line); 418 break; 419 420 case GET_REVISION: 421 processRevision(line); 422 break; 423 424 case GET_DATE: 425 processDate(line); 426 break; 427 428 case GET_COMMENT: 429 processComment(line); 430 break; 431 432 case GET_PREVIOUS_REV: 433 processGetPreviousRevision(line); 434 break; 435 } 436 } 437 438 /*** 439 * Processes a line while in <i>GET_COMMENT</i> state. 440 * @param line the line to process. 441 */ 442 protected void processComment(String line) 443 { 444 if (line != null) 445 { 446 String t_strComment = getComment(); 447 448 String t_strLineSeparator = 449 System.getProperty("line.separator"); 450 451 int t_iEnd; 452 453 if (line.startsWith("======")) 454 { 455 setComment( 456 removeTrailing( 457 t_strComment, 458 t_strLineSeparator.length())); 459 460 //We have ended changelog for that particular file 461 //so we can save it 462 saveEntry(); 463 464 setCurrentState(GET_FILE); 465 466 } 467 else if (line.startsWith("----------------------------")) 468 { 469 setComment( 470 removeTrailing( 471 t_strComment, 472 t_strLineSeparator.length())); 473 474 setCurrentState(GET_PREVIOUS_REV); 475 } 476 else 477 { 478 setComment(line + t_strLineSeparator); 479 } 480 } 481 } 482 483 /*** 484 * Removes trailing substring. 485 * @param input the text to process. 486 * @param suffix the length of the substring to remove at the end. 487 * @return the updated input. 488 */ 489 protected String removeTrailing(String input, int suffix) 490 { 491 String result = input; 492 493 if (input != null) 494 { 495 int t_iAmountToRemove = 496 Math.min(input.length(), suffix); 497 498 result = input.substring(0, input.length() - t_iAmountToRemove); 499 } 500 501 return result; 502 } 503 504 /*** 505 * Processes a line while in <i>GET_FILE</i> state. 506 * @param line the line to process. 507 */ 508 protected void processFile(String line) 509 { 510 if (line != null) 511 { 512 if (line.startsWith("Working file:")) 513 { 514 setName(line.substring(14, line.length())); 515 516 setCurrentState(GET_REVISION); 517 } 518 } 519 } 520 521 /*** 522 * Processes a line while in <i>REVISION</i> state. 523 * @param line the line to process. 524 */ 525 protected void processRevision(String line) 526 { 527 if (line != null) 528 { 529 if (line.startsWith("revision")) 530 { 531 setRevision(line.substring(9)); 532 533 setCurrentState(GET_DATE); 534 } 535 else if (line.startsWith("======")) 536 { 537 //There was no revisions in this changelog 538 //entry so lets move unto next file 539 setCurrentState(GET_FILE); 540 } 541 } 542 } 543 544 /*** 545 * Processes a line while in <i>DATE</i> state. 546 * @param line the line to process. 547 */ 548 protected void processDate(String line) 549 { 550 if (line != null) 551 { 552 if (line.startsWith("date:")) 553 { 554 setDate(line.substring(6, 25)); 555 556 String t_strLineData = 557 line.substring(line.indexOf(";") + 1); 558 559 setAuthor( 560 t_strLineData.substring(10, t_strLineData.indexOf(";"))); 561 562 setCurrentState(GET_COMMENT); 563 564 //Reset comment to empty here as we can accumulate multiple lines 565 //in the processComment method 566 setComment(""); 567 } 568 } 569 } 570 571 /*** 572 * Processes a line while in <i>GET_PREVIOUS_REVISION</i> state. 573 * @param line the line to process. 574 */ 575 protected void processGetPreviousRevision(String line) 576 { 577 if (line != null) 578 { 579 if (!line.startsWith("revision")) 580 { 581 throw new IllegalStateException( 582 "Unexpected line from CVS: " + line); 583 } 584 else 585 { 586 String t_strPreviousRevision = line.substring(9); 587 588 setPreviousRevision(t_strPreviousRevision); 589 590 saveEntry(); 591 592 setRevision(t_strPreviousRevision); 593 594 setCurrentState(GET_DATE); 595 } 596 } 597 } 598 599 /*** 600 * Saves the current entry. 601 */ 602 protected void saveEntry() 603 { 604 CvsEntry t_Entry; 605 606 String t_strDate = getDate(); 607 String t_strAuthor = getAuthor(); 608 String t_strComment = getComment(); 609 610 Object t_EntryKey = buildEntryKey(t_strDate, t_strAuthor, t_strComment); 611 612 Map t_mEntries = getEntries(); 613 614 if (t_mEntries == null) 615 { 616 t_mEntries = new HashMap(); 617 setEntries(t_mEntries); 618 } 619 620 if (t_mEntries.containsKey(t_EntryKey)) 621 { 622 t_Entry = (CvsEntry) t_mEntries.get(t_EntryKey); 623 } 624 else 625 { 626 t_Entry = 627 new CvsEntry( 628 parseDate(t_strDate), t_strAuthor, t_strComment); 629 630 t_mEntries.put(t_EntryKey, t_Entry); 631 } 632 633 t_Entry.add(getName(), getRevision(), getPreviousRevision()); 634 } 635 636 /*** 637 * Parses date out from expected format. 638 * @param date the string holding the date. 639 * @return the date object or <code>null</code> if unknown date format. 640 */ 641 protected Date parseDate(String date) 642 { 643 Date result = null; 644 645 try 646 { 647 result = CVS_LOG_DATE_FORMAT.parse(date); 648 } 649 catch (ParseException parseException) 650 { 651 LogFactory.getLog(ChangeLogParser.class).info( 652 "Couldn't parse date " + date, 653 parseException); 654 } 655 656 return result; 657 } 658 659 /*** 660 * Builds a key for an entry. 661 * @param date the entry's date. 662 * @param author the author. 663 * @param comment the comment. 664 * @return a key for such entry. 665 */ 666 protected Object buildEntryKey(String date, String author, String comment) 667 { 668 return date + author + comment; 669 } 670 671 /*** 672 * Resets all internal attributes except current state. 673 */ 674 protected void reset() 675 { 676 setName(null); 677 setDate(null); 678 setAuthor(null); 679 setComment(null); 680 setRevision(null); 681 setPreviousRevision(null); 682 } 683 } 684

This page was automatically generated by Maven